package com.authsphere.plugin.decrypt;

import com.authsphere.common.utils.JsonUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.JwtParserBuilder;
import io.jsonwebtoken.Jwts;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

/**
 * @program: AuthSphere
 * @description:
 * @author: YuKai Fan
 * @create: 2025/3/13 15:12
 **/
public class JwtRequestBodyDecoder extends AbstractRequestBodyDecoder {

    private static final String AUTH_SPHERE_SECRET_KEY = "META-INF/authsphere/jwt_secret.key";
    private final String secretKey;

    public JwtRequestBodyDecoder(String secretKey) {
        this.secretKey = secretKey;
    }

    public JwtRequestBodyDecoder(ClassLoader classLoader) {
        URL url = Objects.nonNull(classLoader) ? classLoader.getResource(AUTH_SPHERE_SECRET_KEY)
                : ClassLoader.getSystemResource(AUTH_SPHERE_SECRET_KEY);
        if (Objects.nonNull(url)) {
            try (InputStream inputStream = url.openStream()) {
                this.secretKey = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
            } catch (IOException e) {
                throw new RuntimeException("Failed to read secret ket file.", e);
            }
        } else {
            throw new RuntimeException("Secret key file not found in resources.");
        }
    }

    public JwtRequestBodyDecoder() {
        this(JwtRequestBodyDecoder.class.getClassLoader());
    }

    @Override
    protected String doDecrypt(String encoder) {
        return decrypt(encoder, this.secretKey);
    }

    @Override
    public String decrypt(String encryptedData, String secretKey) {
        return checkAuthorization(encryptedData, secretKey);
    }

    private String checkAuthorization(String authorization, String secretKey) {
        if (StringUtils.isBlank(authorization)) {
            return null;
        }
        JwtParserBuilder jwtParserBuilder = Jwts.parserBuilder();
        JwtParser jwtParser = jwtParserBuilder.build();
        if (jwtParser.isSigned(authorization)) {
            jwtParserBuilder.setSigningKey(StringUtils.getBytes(secretKey, StandardCharsets.UTF_8));
            JwtParser jwtParserExec = jwtParserBuilder.build();
            Jws<Claims> jwt = jwtParserExec.parseClaimsJws(authorization);
            if (jwt == null) {
                return null;
            }
            Claims body = jwt.getBody();
            return JsonUtils.toJsonString(body);
        }
        return null;
    }
}
